namespace SharpTalk.Client.WpfApplication.Views
{
    using System.Windows.Media.Imaging;
    using System.Windows;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Controls;
    using System.Collections;
    using System.Windows.Shell;

    public class WindowBase : Window, IView
    {
        private BitArray _topbarButtonsVisibleStates = null;

        private readonly ICommand _closeCommand = null;
        private readonly ICommand _minimizeCommand = null;
        private readonly ICommand _maximizeCommand = null;

        public static readonly DependencyProperty ShowMinimizeButtonProperty = DependencyProperty.Register("ShowMinimizeButton", typeof(bool), typeof(WindowBase), new PropertyMetadata(true));
        public static readonly DependencyProperty ShowMaximizeButtonProperty = DependencyProperty.Register("ShowMaximizeButton", typeof(bool), typeof(WindowBase), new PropertyMetadata(false));
        public static readonly DependencyProperty ShowCloseButtonProperty = DependencyProperty.Register("ShowCloseButton", typeof(bool), typeof(WindowBase), new PropertyMetadata(true));
        
        public static readonly DependencyProperty TopBarBackgroundProperty = DependencyProperty.Register("TopBarBackground", typeof(Brush), typeof(WindowBase));
        public static readonly DependencyProperty TopBarBorderThicknessProperty = DependencyProperty.Register("TopBarBorderThickness", typeof(Thickness), typeof(WindowBase), new PropertyMetadata(new Thickness(0)));
        public static readonly DependencyProperty TopBarBorderBrushProperty = DependencyProperty.Register("TopBarBorderBrush", typeof(Brush), typeof(WindowBase));


        /// <summary>
        /// Creates a new instance
        /// </summary>
        public WindowBase()
        {
            this.TaskbarItemInfo = new TaskbarItemInfo();
        }


        /// <summary>
        /// Obtains or defines if the Minimizebutton should be displayed
        /// </summary>
        public bool ShowMinimizeButton
        {
            get { return (bool)GetValue(ShowMinimizeButtonProperty); }
            set { SetValue(ShowMinimizeButtonProperty, value); }
        }
        /// <summary>
        /// Obtains or define if the Maximize Button should be displayed
        /// </summary>
        public bool ShowMaximizeButton
        {
            get { return (bool)GetValue(ShowMaximizeButtonProperty); }
            set { SetValue(ShowMaximizeButtonProperty, value); }
        }
        /// <summary>
        /// Obtains or defines if the close button should be displayed
        /// </summary>
        public bool ShowCloseButton
        {
            get { return (bool)GetValue(ShowCloseButtonProperty); }
            set { SetValue(ShowCloseButtonProperty, value); }
        }
        /// <summary>
        /// Obtains or defines the TopBar Background
        /// </summary>
        public Brush TopBarBackground
        {
            get { return GetValue(TopBarBackgroundProperty) as Brush; }
            set { SetValue(TopBarBackgroundProperty, value); }
        }
        /// <summary>
        /// Obtains or defines the TopBar BorderBrush
        /// </summary>
        public Brush TopBarBorderBrush
        {
            get { return GetValue(TopBarBorderBrushProperty) as Brush; }
            set { SetValue(TopBarBorderBrushProperty, value); }
        }
        /// <summary>
        /// Obtains or defines the TopBar Thickness
        /// </summary>
        public Thickness TopBarBorderThickness
        {
            get { return (Thickness)GetValue(TopBarBorderBrushProperty); }
            set { SetValue(TopBarBorderBrushProperty, value); }
        }


        public ICommand CloseCommand
        {
            get { return _closeCommand ?? new BindableCommand<object>(OnClose); }
        }

        public ICommand MinimizeCommand
        {
            get { return _minimizeCommand ?? new BindableCommand<object>(OnMinimize); }
        }

        public ICommand MaximizeCommand
        {
            get { return _maximizeCommand ?? new BindableCommand<object>(OnMaximize); }
        }

        /// <summary>
        /// Defines the Window Icon
        /// </summary>
        /// <param name="icon"></param>
        public void SetIcon(BitmapImage icon)
        {
            this.Icon = icon;
        }
        /// <summary>
        /// Show the window in a dialog mode
        /// </summary>
        /// <param name="parent">THe window parent to center the window on</param>
        public bool? ShowDialog(WindowBase parent)
        {
            this.Owner = parent;
            this.WindowStartupLocation = parent == null
                                             ? WindowStartupLocation.CenterScreen
                                             : WindowStartupLocation.CenterOwner;

            var result =  ShowDialog();
            return result;
        }
        
        /// <summary>
        /// Defines if the top bar action buttons should be displayed
        /// </summary>
        /// <param name="visibleState">True to show, false to Hide</param>
        public virtual void SetTopbarActionButtonsState(bool visibleState)
        {
            if(!visibleState)
            {
                if(_topbarButtonsVisibleStates ==null)
                    _topbarButtonsVisibleStates = new BitArray(3);

                // Stores current values
                _topbarButtonsVisibleStates.Set(0,ShowCloseButton);
                _topbarButtonsVisibleStates.Set(1,ShowMinimizeButton);
                _topbarButtonsVisibleStates.Set(2,ShowMaximizeButton);

                // hide buttons
                ShowCloseButton = false;
                ShowMinimizeButton = false;
                ShowMaximizeButton = false;
            }
            else
            {
                // Restore values
                ShowCloseButton = _topbarButtonsVisibleStates.Get(0);
                ShowMinimizeButton = _topbarButtonsVisibleStates.Get(1);
                ShowMaximizeButton = _topbarButtonsVisibleStates.Get(2);

                _topbarButtonsVisibleStates = null;
            }
        }

        private void OnClose(object value)
        {
            this.Close();
        }

        private void OnMinimize(object value)
        {
            this.WindowState = WindowState.Minimized;
        }

        private void OnMaximize(object value)
        {
            this.WindowState =  WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized;
        }
        
        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            if(e.OriginalSource is Border)
            {
                DragMove();
                e.Handled = true;
            }

            base.OnMouseLeftButtonDown(e);
                
        }
    }
}